package com.diaohw.platform.framework.redis.util;


import cn.hutool.extra.spring.SpringUtil;
import com.diaohw.platform.common.util.JsonUtil;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author 刁海文
 * @Remark
 * @since 2023/6/13 21:37
 */
@Service
public class RedisUtil {
    public final static RedisTemplate redis = SpringUtil.getBean(RedisTemplate.class);
    /**
     * 过期时间
     */
    public static int expireTime = 7;

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     */
    public static Boolean expire(String key, long time) {
        return expire(key, time, TimeUnit.DAYS);
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @param unit 时间单位
     */
    public static Boolean expire(String key, long time, TimeUnit unit) {
        return redis.expire(key, time, unit);

    }

    /**
     * 获取符合条件的redis key
     *
     * @param pattern 匹配字符
     * @return Set<String>
     */
    public static Set<String> keys(String pattern) {
        return redis.keys(pattern);
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public static Long getExpire(String key) {
        return redis.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public static Boolean existKey(String key) {
        return redis.hasKey(key);

    }


    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    public static Long delete(String... key) {
        return delete(Arrays.asList(key));
    }

    /**
     * 删除缓存
     *
     * @param keys 可以传一个值 或多个
     */
    public static Long delete(Collection<String> keys) {
        return redis.delete(keys);

    }


    /**
     * 消息广播
     *
     * @param topic   主题
     * @param message 消息
     */
    public static <T> void broadcast(String topic, T message) {
        redis.convertAndSend(topic, JsonUtil.toJsonString(message));
    }


    /**
     * 执行lua脚本
     *
     * @param luaPath 脚本位置
     * @param clazz   执行结果对象类型
     * @param keys    输入的keys
     * @param args    参数
     */
    public static <T> T lua(String luaPath, Class<T> clazz, List<String> keys, Object... args) {
        DefaultRedisScript<T> script = new DefaultRedisScript<T>();

        script.setScriptSource(new ResourceScriptSource(new ClassPathResource(luaPath)));
        script.setResultType(clazz);

        return (T) redis.execute(script, keys, args);
    }
}
